#!/user/bin/python
#encoding:utf-8

import sys
import re
import pdb

class pig:
    def __init__(self):
        self.my_id = 0
        self.my_type = ""
        self.my_name = ""
        self.parent_id = []
        self.my_filter = ""
        self.my_generate = ""
        self.my_streaming = ""

    def about(self, alls):
        print "++++++++++ a pig coming ++++++"
        print "my id %s" % self.my_id
        print "my name is %s" % self.my_name
        print "my father is %s" % str(getFatherNameByID(self.parent_id, alls))
        print "my generate is %s" % self.my_generate
        print "++++++++++ welcome another pig ++++++"

def getFatherNameByID(parent_ids, alls):
        father_name = []
        if len(parent_ids) == 0:
            father_name.append("I'm the father")
        else:
            for parent_id in parent_ids:
                for apig in alls:
                    if alls[apig].my_id == parent_id:
                        father_name.append(alls[parent_id].my_name)
        #return ','.join(father_name)
        return father_name

def getParentIDSByNames(parent_names, alls):
        parent_ids = []
        if len(parent_names) == 0:
            father_name = "I'm the father"
        else:
            for pname in parent_names:
                for apig in alls:
                    if alls[apig].my_name == pname:
                        parent_ids.append(alls[apig].my_id)
        return parent_ids

def printForGraph(pigs):
    '''
    digraph {
        /* Note: HTML labels do not work in IE, which lacks support for &lt;foreignObject&gt; tags. */
        A [label="<div style='padding: 10px;'>A <span style='font-size:32px'>Big</span> <span style='color:red;'>HTML</span> Source!</div>"];    C;
        E [label="A sink"];
        A -> B -> C;
        B -> D -> E;
        C -> E;
        A -> D [label="<div>A multi-rank <span style='color:blue;'>HTML</span> edge!</div>"];
    }'''
    graph_str = "digraph { \n"
    for apig in pigs:
        for father in getFatherNameByID(pigs[apig].parent_id, pigs):
            if not father == "I'm the father" :
                #graph_str += '''%s [label = "<div><span style='color:red;'>%s</span> = %s</div>"] ; \n'''  %( pigs[apig].my_name, pigs[apig].my_name, pigs[apig].my_generate )
                graph_str += "%s -> %s ; \n"  %(father, pigs[apig].my_name)
    graph_str += "}"
    print graph_str

def getList(regex,text):
    '''
    输入：正则表达式，文本
    输出：匹配到的数组(默认使用findall匹配)
    '''
    res = re.findall(regex, text)
    if res:
        for r in res:
            return r

def skipLine(line):
    '''判断是否跳过解析:一般跳过空行,注释行,set,register'''
    marks = ['--','register','set ', 'dump']
    res = False
    for mark in marks:
        if mark == line.lower()[:len(mark)]:
            res = True
    return res

def upperLine(line):
    '''确保关键字大写'''
    keywords = [" load "," filter "," join "," stream "," group "," flatten"," by "," generate "," through "," foreach "]
    for keyword in keywords:
        line = line.replace(keyword, keyword.upper())
    return line

def getOpts():
    if len(sys.argv) != 2:
        print "use pigsty.py <filepath>"
        exit(0)
    else:
        filepath = sys.argv[1]
        return filepath

def main():
    filepath = getOpts()
    id_counter = 1
    pigs = {}
    for line in open(filepath):
        try:
            if skipLine(line):
                #print "skip", line
                continue
            line = upperLine(line)

            if line.find('LOAD') != -1:
                load_list = line.strip(' ').split('=')
                pigs[id_counter] = pig()
                pigs[id_counter].my_id = id_counter
                pigs[id_counter].my_name = load_list[0].strip(' ')
                pigs[id_counter].my_type = "LOAD"
                id_counter += 1
            elif line.find('FILTER') != -1:
                filter_list = getList(u"^([\S]+).*=.*FILTER\s([\S]+).*GENERATE\s([^;)]+)", line )
                pigs[id_counter] = pig()
                pigs[id_counter].my_id = id_counter
                pigs[id_counter].my_name = filter_list[0]
                pigs[id_counter].my_type = "FILTER"
                pigs[id_counter].my_generate = filter_list[-1]
                pigs[id_counter].parent_id = getParentIDSByNames(filter_list[1:-1], pigs) 
                id_counter += 1
            elif line.find(' JOIN ') != -1:
                join_list = getList(u"^([\S]+).*=.*JOIN[\s]+([\S]+).*,[\s]+([\S]+)[\s]+BY.*GENERATE\s([^;)]+)", line )
                pigs[id_counter] = pig()
                pigs[id_counter].my_id = id_counter
                pigs[id_counter].my_name = join_list[0]
                pigs[id_counter].my_type = "JOIN"
                pigs[id_counter].my_generate = join_list[-1]
                pigs[id_counter].parent_id = getParentIDSByNames(join_list[1:-1], pigs) 
                id_counter += 1
            elif line.find('STREAM ') != -1:
                stream_list = getList(u"^([\S]+).*=.*STREAM\s([\S]+).*THROUGH.*([\S]+).*", line )
                pigs[id_counter] = pig()
                pigs[id_counter].my_id = id_counter
                pigs[id_counter].my_name = stream_list[0]
                pigs[id_counter].my_type = "STREAM"
                pigs[id_counter].my_generate = stream_list[-1]
                pigs[id_counter].parent_id = getParentIDSByNames(stream_list[1:-1], pigs) 
                id_counter += 1
            elif line.find(' GROUP ') != -1:
                #if line[:len("CPS_GROUP")] == "CPS_GROUP":
                #print "here ++++++++++"
                group_list = getList(u"^([\S]+).*=.*GROUP\s([\S]+).*BY[\s]+([\S]+)", line )
                pigs[id_counter] = pig()
                pigs[id_counter].my_id = id_counter
                pigs[id_counter].my_name = group_list[0]
                pigs[id_counter].my_type = "GROUP"
                pigs[id_counter].my_generate = group_list[-1]
                pigs[id_counter].parent_id = getParentIDSByNames(group_list[1:-1], pigs) 
                id_counter += 1
            elif line.find('FLATTEN') != -1:
                flat_list = getList(u"^([\S]+).*=.*FOREACH\s([\S]+).*FLATTEN\(([\S]+)\).*", line )
                pigs[id_counter] = pig()
                pigs[id_counter].my_id = id_counter
                pigs[id_counter].my_name = flat_list[0]
                pigs[id_counter].my_type = "FLATTEN"
                pigs[id_counter].my_generate = flat_list[-1]
                pigs[id_counter].parent_id = getParentIDSByNames(flat_list[1:-1], pigs) 
                id_counter += 1
            else :
                pass
        except Exception , e:
            print e
            print line

    #for apig in pigs:
    #    pigs[apig].about(pigs)
    
    printForGraph(pigs)

if __name__ == '__main__':
    main()
